<template>
  <div class="filter-bar">
    <div class="bar-main">
      <BoolQuery
        :allFields="allFields"
        :level="1"
        :queryConditionTree="queryConditionTree"
        @addCondition="handleAddCondition"
        @delCondition="handleDelCondition"
        @alterCondition="handleAlterCondition"
      >
      </BoolQuery>
    </div>
    <div class="bar-btn">
      <el-button size="small" type="primary" @click="query">查询</el-button>
    </div>
  </div>
</template>

<script>
import Vue from 'vue';
import { v4 as guid } from 'uuid';

import BoolQuery from './boolQuery.vue';
import { fieldTypes, queryTypes, boolTypes } from '../queryDef';

export default {
  name: 'queryFilterBar',
  components: {
    BoolQuery,
  },
  props: ['allFields', 'operators'],
  data() {
    return {
      fieldTypes,
      queryTypes,
      boolTypes,
      formData: {
        field: '',
        operator: '',
        inputValue: '',
        dateRangeStart: '',
        dateRangeEnd: '',
        numRangeStart: '',
        numRangeEnd: '',
      },
      popoverVisible: false,
      showOperator: false,
      selectedFieldType: '',
      rules: {
        field: [{ required: true, message: '必选' }],
        operator: [{ required: true, message: '必选' }],
      },
      availableOperators: [],

      //
      queryConditions: [],

      topLevelBoolId: '1',

      queryConditionTree: {
        id: '1',
        parentId: '',
        boolType: 1,
        children: [],
      },
    };
  },
  computed: {},
  methods: {
    handleAddCondition(condition) {
      const { parentData, childData } = condition;

      const find_parent = this.queryConditions.find(
        x => x.id === parentData.id
      );

      if (find_parent) {
        find_parent.boolType = parentData.boolType;
      } else {
        this.queryConditions.push(parentData);
      }

      if (childData.type === 'bool') {
        const newId = guid();
        const newBool = {
          id: newId,
          parentId: parentData.id,
          boolType: childData.boolType,
          type: 'bool',
        };

        this.queryConditions.push(newBool);

        const newQuery = {
          id: guid(),
          parentId: newId,
          fieldId: childData.fieldId,
          operatorId: childData.operatorId,
          value: childData.value,
          type: 'field',
        };

        this.queryConditions.push(newQuery);
      } else {
        if (childData.type === 'field') {
          const newQuery = {
            id: guid(),
            parentId: parentData.id,
            fieldId: childData.fieldId,
            operatorId: childData.operatorId,
            value: childData.value,
            type: 'field',
          };

          this.queryConditions.push(newQuery);
        }
      }

      // 刷新UI
      const topLevelBool = this.queryConditions.find(
        x => x.id == this.topLevelBoolId
      );

      this.arrayToTree(this.topLevelBoolId, this.queryConditions, topLevelBool);
      Vue.set(this.queryConditionTree, 'children', topLevelBool.children);

      console.log(this.queryConditionTree);
    },

    handleDelCondition(condition) {
      let i;
      for (i = 0; i < this.queryConditions.length; i++) {
        if (this.queryConditions[i].id === condition.id) {
          this.queryConditions.splice(i, 1);
        }
      }

      if (condition.parentId !== this.topLevelBoolId) {
        const broConditions = this.queryConditions.filter(
          x => x.parentId === condition.parentId
        );
        if (broConditions.length < 1) {
          let j;
          for (j = 0; j < this.queryConditions.length; j++) {
            if (this.queryConditions[j].id === condition.parentId) {
              this.queryConditions.splice(j, 1);
            }
          }
        }
      }

      // 刷新UI
      const topLevelBool = this.queryConditions.find(
        x => x.id == this.topLevelBoolId
      );

      this.arrayToTree(this.topLevelBoolId, this.queryConditions, topLevelBool);
      Vue.set(this.queryConditionTree, 'children', topLevelBool.children);

      console.log(this.queryConditionTree);
    },

    arrayToTree(parentId, allData, parentData) {
      const children = allData.filter(x => x.parentId === parentId);

      if (children && children.length > 0) {
        for (let child of children) {
          this.arrayToTree(child.id, allData, child);
        }
      }

      parentData.children = children;
    },

    handleAlterCondition({ id, boolType }) {
      for (let con of this.queryConditions) {
        if (con.id === id) {
          con.boolType = boolType;
          break;
        }
      }

      console.log(this.queryConditions);
    },

    query() {
      let queryData = {};

      console.log('queryConditions: ', this.queryConditions);
      const queries = this.queryConditions.filter(
        x => x.parentId === this.topLevelBoolId
      );
      if (queries.length > 0) {
        const boolQuery = this.createQuery(this.topLevelBoolId);

        queryData = boolQuery;
      }

      console.log('result: ', queryData);
      this.$emit('query', queryData);
    },

    createQuery(parentId) {
      const queryData = {};
      const parent = this.queryConditions.find(x => x.id === parentId);

      const children = this.queryConditions.filter(
        x => x.parentId === parentId
      );

      const convertChildren = [];

      for (let child of children) {
        if (child.type === 'field') {
          // 创建 field
          const fieldName = this.allFields.find(x => x.id === child.fieldId)
            .fieldEnName;

          const queryType = this.queryTypes.find(x => x.id === child.operatorId)
            .value;

          const fieldValue = {};
          fieldValue[fieldName] = child.value;

          const obj = {};
          obj[queryType] = fieldValue;

          convertChildren.push(obj);
        } else if (child.type === 'bool') {
          const newBool = this.createQuery(child.id);
          convertChildren.push(newBool);
        }
      }

      if (parent) {
        const boolValue = boolTypes.find(x => x.id === parent.boolType).value;

        const childBoolQuery = {};

        childBoolQuery[boolValue] = convertChildren;

        queryData.bool = childBoolQuery;
      }

      return queryData;
    },
  },
};
</script>

<style scoped>
.filter-bar {
  width: 100%;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: space-between;
  align-items: center;
  align-content: center;
  background-color: #fafbfd;
  padding: 0 8px;
}

.bar-main {
  width: 100%;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: center;
  align-content: center;
}

.bar-btn {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
}

.filter-item {
  margin: 0 5px;
  display: flex;
  flex-wrap: wrap;
}

.add-filter {
  margin: 0 5px;
}

.link-button {
  margin-left: 5px;
  color: #0071c2;
}

.link-button:hover {
  cursor: pointer;
  text-decoration: underline;
}

.pop-card {
  width: 100%;
  display: flex;
  flex-direction: column;
}

.card-header {
  width: 100%;
  display: flex;
  flex-direction: row;
  font-size: 30px;
  font-weight: 700;
  margin-bottom: 10px;
}

.cared-body {
  width: 100%;
  display: flex;
  flex-direction: column;
}

.card-footer {
  width: 100%;
  display: inline-flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: flex-end;
}

.nl-form-row {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: space-between;
}
</style>
